///*
// * RED5 Open Source Media Server - https://github.com/Red5/ Copyright 2006-2016 by respective authors (see below). All rights reserved. Licensed under the Apache License, Version
// * 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless
// * required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// * either express or implied. See the License for the specific language governing permissions and limitations under the License.
// */
//
//package org.red5.server.war;
//
//import java.beans.Introspector;
//import java.io.File;
//import java.sql.Driver;
//import java.sql.DriverManager;
//import java.util.ArrayList;
//import java.util.Enumeration;
//
//import javax.servlet.ServletContext;
//import javax.servlet.ServletContextEvent;
//
//import zx.zxlive.io.io.amf.Output;
//import org.red5.logging.Red5LoggerFactory;
//import org.red5.server.ClientRegistry;
//import org.red5.server.Context;
//import org.red5.server.MappingStrategy;
//import org.red5.server.Server;
//import org.red5.server.api.Red5;
//import org.red5.server.scope.GlobalScope;
//import org.red5.server.scope.ScopeResolver;
//import org.red5.server.scope.WebScope;
//import org.red5.server.service.ServiceInvoker;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.beans.factory.config.ConfigurableBeanFactory;
//import org.springframework.beans.factory.support.DefaultListableBeanFactory;
//import org.springframework.web.context.ConfigurableWebApplicationContext;
//import org.springframework.web.context.ContextLoader;
//import org.springframework.web.context.ContextLoaderListener;
//import org.springframework.web.context.WebApplicationContext;
//
//import ch.qos.logback.classic.LoggerContext;
//
///**
// * Entry point from which the server config file is loaded while running within a J2EE application container.
// *
// * This listener should be registered after Log4jConfigListener in web.xml, if the latter is used.
// *
// * @author The zSharpe Project
// * @author Vic Wang (xiaoyu860912@163.com)
// */
//public class WarLoaderServlet extends ContextLoaderListener {
//
//    // Initialize Logging
//    public static final Logger logger = Red5LoggerFactory.getLogger(WarLoaderServlet.class);
//
//    private static ArrayList<ServletContext> registeredContexts = new ArrayList<ServletContext>(3);
//
//    private ConfigurableWebApplicationContext applicationContext;
//
//    private DefaultListableBeanFactory parentFactory;
//
//    private static ServletContext servletContext;
//
//    private ClientRegistry clientRegistry;
//
//    private ServiceInvoker globalInvoker;
//
//    private MappingStrategy globalStrategy;
//
//    private ScopeResolver globalResolver;
//
//    private GlobalScope global;
//
//    private Server server;
//
//    /**
//     * Main entry point for the Red5 Server as a war
//     */
//    // Notification that the web application is ready to process requests
//    @Override
//    public void contextInitialized(ServletContextEvent sce) {
//        if (null != servletContext) {
//            return;
//        }
//        System.setProperty("red5.deployment.type", "war");
//
//        servletContext = sce.getServletContext();
//        String prefix = servletContext.getRealPath("/");
//
//        if (System.getProperty("red5.webapp.root") == null) {
//            File webapps = new File(prefix);
//            System.setProperty("red5.webapp.root", webapps.getParent());
//            webapps = null;
//        }
//
//        long time = System.currentTimeMillis();
//
//        logger.info("{} WAR loader", Red5.VERSION);
//        logger.debug("Path: {}", prefix);
//
//        try {
//            //use super to initialize
//            super.contextInitialized(sce);
//            //get the web context
//            applicationContext = (ConfigurableWebApplicationContext) servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
//            logger.debug("Root context path: {}", applicationContext.getServletContext().getContextPath());
//
//            ConfigurableBeanFactory factory = applicationContext.getBeanFactory();
//
//            // register default
//            factory.registerSingleton("default.context", applicationContext);
//
//            // get the main factory
//            parentFactory = (DefaultListableBeanFactory) factory.getParentBeanFactory();
//
//        } catch (Throwable t) {
//            logger.error("", t);
//        }
//
//        long startupIn = System.currentTimeMillis() - time;
//        logger.info("Startup done in: {} ms", startupIn);
//
//    }
//
//    /*
//     * Registers a subcontext with red5
//     */
//    public void registerSubContext(String webAppKey) {
//        // get the sub contexts - servlet context
//        ServletContext ctx = servletContext.getContext(webAppKey);
//        if (ctx == null) {
//            ctx = servletContext;
//        }
//        ContextLoader loader = new ContextLoader();
//        ConfigurableWebApplicationContext appCtx = (ConfigurableWebApplicationContext) loader.initWebApplicationContext(ctx);
//        appCtx.setParent(applicationContext);
//        appCtx.refresh();
//
//        ctx.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, appCtx);
//
//        ConfigurableBeanFactory appFactory = appCtx.getBeanFactory();
//
//        logger.debug("About to grab Webcontext bean for {}", webAppKey);
//        Context webContext = (Context) appCtx.getBean("web.context");
//        webContext.setCoreBeanFactory(parentFactory);
//        webContext.setClientRegistry(clientRegistry);
//        webContext.setServiceInvoker(globalInvoker);
//        webContext.setScopeResolver(globalResolver);
//        webContext.setMappingStrategy(globalStrategy);
//
//        WebScope scope = (WebScope) appFactory.getBean("web.scope");
//        scope.setServer(server);
//        scope.setParent(global);
//        scope.register();
//        scope.start();
//
//        // register the context so we dont try to reinitialize it
//        registeredContexts.add(ctx);
//
//    }
//
//    /**
//     * Clearing the in-memory configuration parameters, we will receive notification that the servlet context is about to be shut down
//     */
//    @Override
//    public void contextDestroyed(ServletContextEvent sce) {
//        synchronized (servletContext) {
//            logger.info("Webapp shutdown");
//            // XXX Paul: grabbed this from
//            // http://opensource.atlassian.com/confluence/spring/display/DISC/Memory+leak+-+classloader+won%27t+let+go
//            // in hopes that we can clear all the issues with J2EE containers
//            // during shutdown
//            ServletContext ctx = null;
//            try {
//                ctx = sce.getServletContext();
//                // prepare spring for shutdown
//                Introspector.flushCaches();
//                // dereg any drivers
//                for (Enumeration<?> e = DriverManager.getDrivers(); e.hasMoreElements();) {
//                    Driver driver = (Driver) e.nextElement();
//                    if (driver.getClass().getClassLoader() == getClass().getClassLoader()) {
//                        DriverManager.deregisterDriver(driver);
//                    }
//                }
//                // clear the AMF output cache
//                Output.destroyCache();
//                // stop the logger
//                try {
//                    ((LoggerContext) LoggerFactory.getILoggerFactory()).stop();
//                } catch (Exception e) {
//                }
//                // shutdown spring
//                Object attr = ctx.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
//                if (attr != null) {
//                    // get web application context from the servlet context
//                    ConfigurableWebApplicationContext applicationContext = (ConfigurableWebApplicationContext) attr;
//                    ConfigurableBeanFactory factory = applicationContext.getBeanFactory();
//                    // for (String scope : factory.getRegisteredScopeNames()) {
//                    // logger.debug("Registered scope: " + scope);
//                    // }
//                    try {
//                        for (String singleton : factory.getSingletonNames()) {
//                            logger.debug("Registered singleton: {}", singleton);
//                            factory.destroyScopedBean(singleton);
//                        }
//                    } catch (RuntimeException e) {
//                    }
//                    factory.destroySingletons();
//                    applicationContext.close();
//                }
//            } catch (Throwable e) {
//                logger.warn("Exception {}", e);
//            } finally {
//                super.contextDestroyed(sce);
//                if (ctx != null) {
//                    ctx.removeAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
//                }
//            }
//        }
//    }
//
//}
